extends Node2D
class_name EnemyManager

# 敌人管理器 - 负责动态生成和管理所有敌人

# 敌人预制体路径
const SLIME_SCENE = preload("res://Scenes/Entities/Slime.tscn")
const GOBLIN_SCENE = preload("res://Scenes/Entities/Goblin.tscn")
const FLYING_CREATURE_SCENE = preload("res://Scenes/Entities/FlyingCreature.tscn")

# 敌人配置
@export_group("敌人数量配置")
@export var base_slime_count: int = 2
@export var base_goblin_count: int = 1
@export var base_flying_creature_count: int = 1
@export var enemies_per_room: float = 1.5  # 每个房间平均敌人数量

@export_group("生成配置")
@export var spawn_delay_between_enemies: float = 0.5  # 敌人生成间隔
@export var spawn_effect_duration: float = 1.0  # 生成特效持续时间
@export var min_distance_from_player: float = 50.0  # 与玩家的最小距离

# 内部变量
var spawned_enemies: Array[BaseEnemy] = []
var spawn_points: Array[Vector2i] = []
var dungeon_rooms: Array = []
var tilemap: TileMap
var is_spawning: bool = false

# 引用
var game_controller: Node2D
var player: CharacterBody2D

# 信号
signal enemy_spawned(enemy: BaseEnemy)
signal all_enemies_spawned()
signal enemy_died(enemy: BaseEnemy)
signal victory_achieved()  # 新增：通关信号

func _ready():
	print("🏭 敌人管理器初始化...")
	add_to_group("enemy_manager")

func initialize(game_node: Node2D):
	"""初始化敌人管理器"""
	game_controller = game_node
	player = game_node.get_node_or_null("Player")
	tilemap = game_node.get_node_or_null("TileMap")
	
	print("✅ 敌人管理器初始化完成")

func start_spawning(rooms: Array, spawn_points_array: Array[Vector2i]):
	"""开始生成敌人"""
	if is_spawning:
		print("⚠️ 敌人正在生成中，忽略重复请求")
		return
	
	print("🏭 开始生成敌人...")
	print("📊 收到房间数量: ", rooms.size())
	print("📍 收到生成点数量: ", spawn_points_array.size())
	
	is_spawning = true
	
	# 清理现有敌人
	clear_all_enemies()
	
	# 保存地牢信息
	dungeon_rooms = rooms
	spawn_points = spawn_points_array
	
	# 打印生成点详细信息
	print("📍 生成点详细信息:")
	for i in range(min(spawn_points.size(), 5)):  # 只打印前5个避免输出过多
		var spawn_point = spawn_points[i]
		var world_pos = tilemap.map_to_local(spawn_point) if tilemap else Vector2(spawn_point.x * 16, spawn_point.y * 16)
		print("  ", i, ": 瓦片坐标=", spawn_point, " 世界坐标=", world_pos)
	
	# 计算需要生成的敌人数量
	var enemy_counts = calculate_enemy_counts()
	print("📊 计划生成敌人: Slime=", enemy_counts.slime, " Goblin=", enemy_counts.goblin, " FlyingCreature=", enemy_counts.flying_creature)
	
	# 开始异步生成
	spawn_enemies_async(enemy_counts)

func calculate_enemy_counts() -> Dictionary:
	"""根据地牢大小计算敌人数量"""
	var room_count = dungeon_rooms.size()
	var total_enemies = max(1, int(room_count * enemies_per_room))
	
	# 基础数量 + 根据房间数量的额外数量
	var extra_enemies = max(0, total_enemies - (base_slime_count + base_goblin_count + base_flying_creature_count))
	
	# 分配额外敌人（优先分配给Slime，因为它们比较弱）
	var slime_count = base_slime_count + max(0, extra_enemies - 2)
	var goblin_count = base_goblin_count + min(1, extra_enemies)
	var flying_creature_count = base_flying_creature_count + min(1, max(0, extra_enemies - 1))
	
	return {
		"slime": slime_count,
		"goblin": goblin_count,
		"flying_creature": flying_creature_count
	}

func spawn_enemies_async(enemy_counts: Dictionary):
	"""异步生成敌人"""
	var enemies_to_spawn = []
	
	# 准备生成列表
	for i in enemy_counts.slime:
		enemies_to_spawn.append("slime")
	for i in enemy_counts.goblin:
		enemies_to_spawn.append("goblin")
	for i in enemy_counts.flying_creature:
		enemies_to_spawn.append("flying_creature")
	
	# 随机打乱生成顺序
	enemies_to_spawn.shuffle()
	
	print("🎲 敌人生成顺序: ", enemies_to_spawn)
	
	# 逐个生成敌人
	for i in range(enemies_to_spawn.size()):
		var enemy_type = enemies_to_spawn[i]
		await spawn_single_enemy(enemy_type, i)
		
		# 生成间隔
		if i < enemies_to_spawn.size() - 1:
			await get_tree().create_timer(spawn_delay_between_enemies).timeout
	
	is_spawning = false
	all_enemies_spawned.emit()
	print("🎉 所有敌人生成完成！总数: ", spawned_enemies.size())

func spawn_single_enemy(enemy_type: String, index: int) -> BaseEnemy:
	"""生成单个敌人"""
	print("👹 生成敌人: ", enemy_type, " (", index + 1, ")")
	
	# 选择生成位置
	var spawn_position = get_valid_spawn_position()
	if spawn_position == Vector2.ZERO:
		print("❌ 无法找到有效的生成位置")
		return null
	
	print("📍 选定生成位置: ", spawn_position)
	
	# 验证最终位置
	if tilemap:
		var final_tile_pos = tilemap.local_to_map(spawn_position)
		var final_atlas_coords = tilemap.get_cell_atlas_coords(0, final_tile_pos)
		print("🔍 最终位置验证: 瓦片坐标=", final_tile_pos, " 图集坐标=", final_atlas_coords)
	
	# 创建敌人实例
	var enemy_scene = get_enemy_scene(enemy_type)
	if not enemy_scene:
		print("❌ 无法加载敌人场景: ", enemy_type)
		return null
	
	var enemy = enemy_scene.instantiate()
	if not enemy:
		print("❌ 无法实例化敌人: ", enemy_type)
		return null
	
	# 设置位置并添加到场景
	enemy.global_position = spawn_position
	enemy.visible = false  # 先隐藏，等特效完成后显示
	game_controller.add_child(enemy)
	
	print("✅ 敌人已添加到场景: ", enemy.name, " 位置: ", enemy.global_position)
	
	# 连接敌人死亡信号
	if enemy.has_signal("died"):
		enemy.died.connect(_on_enemy_died)
	
	# 添加到管理列表
	spawned_enemies.append(enemy)
	enemy.add_to_group("enemies")
	
	# 播放生成特效
	await play_spawn_effect(spawn_position, enemy)
	
	print("✅ 敌人生成完成: ", enemy.name, " 最终位置: ", enemy.global_position)
	enemy_spawned.emit(enemy)
	
	return enemy

func get_enemy_scene(enemy_type: String) -> PackedScene:
	"""获取敌人场景"""
	match enemy_type:
		"slime":
			return SLIME_SCENE
		"goblin":
			return GOBLIN_SCENE
		"flying_creature":
			return FLYING_CREATURE_SCENE
		_:
			print("❌ 未知的敌人类型: ", enemy_type)
			return null

func get_valid_spawn_position() -> Vector2:
	"""获取有效的生成位置"""
	var max_attempts = 50
	var attempts = 0
	
	print("🔍 开始寻找有效生成位置...")
	print("📍 可用生成点数量: ", spawn_points.size())
	
	while attempts < max_attempts:
		attempts += 1
		
		# 从可用的生成点中随机选择一个
		if spawn_points.size() == 0:
			print("❌ 没有可用的生成点")
			return Vector2.ZERO
		
		var random_spawn_point = spawn_points[randi() % spawn_points.size()]
		var world_position = Vector2.ZERO
		
		# 安全的坐标转换
		if tilemap:
			world_position = tilemap.map_to_local(random_spawn_point)
		else:
			# 如果没有tilemap，假设是直接的像素坐标
			world_position = Vector2(random_spawn_point.x * 16, random_spawn_point.y * 16)
		
		# 只在前几次尝试时打印详细信息
		if attempts <= 3:
			print("🎲 尝试 ", attempts, ": 瓦片坐标=", random_spawn_point, " 世界坐标=", world_position)
		
		# 检查是否距离玩家足够远
		if player and world_position.distance_to(player.global_position) < min_distance_from_player:
			if attempts <= 3:
				print("⚠️ 距离玩家太近: ", world_position.distance_to(player.global_position))
			continue
		
		# 检查位置是否有效（不在墙壁中）
		if is_position_valid(world_position):
			print("✅ 找到有效位置: ", world_position, " (尝试 ", attempts, " 次)")
			return world_position
		elif attempts <= 3:
			print("❌ 位置无效（在墙壁中）: ", world_position)
	
	print("⚠️ 尝试", max_attempts, "次后仍无法找到有效位置，使用备用位置")
	return get_fallback_spawn_position()

func is_position_valid(position: Vector2) -> bool:
	"""检查位置是否有效"""
	if not tilemap:
		return true
	
	var tile_pos = tilemap.local_to_map(position)
	var source_id = tilemap.get_cell_source_id(0, tile_pos)
	var atlas_coords = tilemap.get_cell_atlas_coords(0, tile_pos)
	
	# 如果没有瓦片，说明是空白区域，不适合生成
	if source_id == -1:
		return false
	
	# 检查是否是地板瓦片（根据DungeonGenerator中的定义）
	var floor_tiles = [
		Vector2i(3, 4),  # TileType.FLOOR
		Vector2i(4, 4),  # TileType.FLOOR_VARIANT1
		Vector2i(3, 5),  # TileType.FLOOR_VARIANT2
		Vector2i(4, 5),  # TileType.FLOOR_VARIANT3
		Vector2i(3, 1),  # 走廊（如果有的话）
	]
	
	var is_floor = atlas_coords in floor_tiles
	
	return is_floor

func get_fallback_spawn_position() -> Vector2:
	"""获取备用生成位置"""
	print("🎯 计算备用生成位置...")
	
	if not tilemap:
		print("⚠️ 没有tilemap，使用默认位置")
		return Vector2(240, 135)  # 默认中心位置
	
	# 尝试找到地牢中心的地板位置
	var used_rect = tilemap.get_used_rect()
	print("📏 TileMap使用区域: ", used_rect)
	
	# 从中心开始，螺旋式搜索地板瓦片
	var center_tile = used_rect.position + used_rect.size / 2
	var search_radius = 1
	var max_search_radius = 10
	
	while search_radius <= max_search_radius:
		for x_offset in range(-search_radius, search_radius + 1):
			for y_offset in range(-search_radius, search_radius + 1):
				# 只检查当前半径边缘的点
				if abs(x_offset) != search_radius and abs(y_offset) != search_radius:
					continue
				
				var test_tile = center_tile + Vector2i(x_offset, y_offset)
				var test_world_pos = tilemap.map_to_local(test_tile)
				
				if is_position_valid(test_world_pos):
					print("✅ 备用位置找到: 瓦片坐标=", test_tile, " 世界坐标=", test_world_pos)
					return test_world_pos
		
		search_radius += 1
	
	# 如果还是找不到，使用地图中心
	var center_world = tilemap.map_to_local(center_tile)
	print("⚠️ 使用地图中心作为最后备用位置: ", center_world)
	return center_world

func play_spawn_effect(position: Vector2, enemy: BaseEnemy) -> void:
	"""播放生成特效"""
	print("✨ 播放生成特效: ", position)
	
	# 创建生成特效
	var spawn_effect = create_spawn_effect(position)
	
	# 等待特效播放一段时间后显示敌人
	await get_tree().create_timer(spawn_effect_duration * 0.6).timeout
	
	if enemy and is_instance_valid(enemy):
		# 敌人淡入效果
		enemy.visible = true
		enemy.modulate = Color(1, 1, 1, 0)  # 完全透明
		
		var tween = create_tween()
		if tween:
			tween.tween_property(enemy, "modulate", Color.WHITE, 0.5)
	
	# 等待特效完全结束
	await get_tree().create_timer(spawn_effect_duration * 0.4).timeout

func create_spawn_effect(position: Vector2) -> Node2D:
	"""创建生成特效"""
	var effect_container = Node2D.new()
	game_controller.add_child(effect_container)
	effect_container.global_position = position
	
	# 魔法阵效果
	var magic_circle = Sprite2D.new()
	effect_container.add_child(magic_circle)
	magic_circle.name = "MagicCircle"  # 给节点命名，方便后续查找
	
	# 安全加载纹理
	var explosion_texture = load("res://Art/v1.1 dungeon crawler 16X16 pixel pack/effects (new)/explosion_anim_spritesheet.png")
	if explosion_texture:
		magic_circle.texture = explosion_texture
		magic_circle.hframes = 7
		magic_circle.modulate = Color.CYAN
		magic_circle.scale = Vector2(0.1, 0.1)
	else:
		print("⚠️ 无法加载爆炸特效纹理，使用简化特效")
		# 创建简单的彩色圆形作为备用特效
		magic_circle.texture = null
		magic_circle.modulate = Color.CYAN
		magic_circle.scale = Vector2(0.5, 0.5)
	
	# 粒子效果（简单的发光点）
	for i in range(8):
		var particle = Sprite2D.new()
		effect_container.add_child(particle)
		particle.name = "Particle" + str(i)  # 给粒子命名
		
		# 安全加载粒子纹理
		var hit_texture = load("res://Art/v1.1 dungeon crawler 16X16 pixel pack/effects (new)/hit_effect_anim_spritesheet.png")
		if hit_texture:
			particle.texture = hit_texture
			particle.hframes = 3
		else:
			# 使用简单的彩色方块作为备用
			particle.texture = null
		
		particle.modulate = Color(randf_range(0.5, 1), randf_range(0.5, 1), 1, 0.8)
		particle.scale = Vector2(0.5, 0.5)
		
		var angle = i * PI / 4
		var radius = 20
		particle.position = Vector2(cos(angle), sin(angle)) * radius
	
	# 动画效果
	var tween = create_tween()
	tween.set_parallel(true)
	
	# 魔法阵动画 - 使用节点路径而不是直接捕获变量
	if magic_circle and is_instance_valid(magic_circle):
		tween.tween_property(magic_circle, "scale", Vector2(1.5, 1.5), spawn_effect_duration * 0.7)
		tween.tween_property(magic_circle, "modulate:a", 0.0, spawn_effect_duration)
		
		# 只有在有纹理且hframes大于1时才播放帧动画
		if magic_circle.texture and magic_circle.hframes > 1:
			# 使用更安全的方式：通过effect_container查找子节点
			var max_frame = magic_circle.hframes - 1
			var container_id = effect_container.get_instance_id()
			tween.tween_method(
				func(frame): 
					var container = instance_from_id(container_id)
					if container and is_instance_valid(container):
						var circle = container.get_node_or_null(NodePath("MagicCircle"))
						if circle:
							circle.frame = frame,
				0, max_frame, spawn_effect_duration * 0.8
			)
	
	# 粒子动画 - 使用节点路径而不是直接引用
	for i in range(8):
		var particle_name = "Particle" + str(i)
		var particle = effect_container.get_node_or_null(NodePath(particle_name))
		if particle and is_instance_valid(particle):
			var final_pos = particle.position * 2
			tween.tween_property(particle, "position", final_pos, spawn_effect_duration)
			tween.tween_property(particle, "modulate:a", 0.0, spawn_effect_duration)
	
	# 清理特效 - 使用更安全的方式
	var container_id = effect_container.get_instance_id()
	tween.tween_callback(
		func(): 
			var container = instance_from_id(container_id)
			if container and is_instance_valid(container):
				container.queue_free()
	)
	
	return effect_container

func clear_all_enemies():
	"""清理所有现有敌人"""
	print("🧹 清理现有敌人...")
	
	for enemy in spawned_enemies:
		if enemy and is_instance_valid(enemy):
			enemy.queue_free()
	
	spawned_enemies.clear()
	print("✅ 敌人清理完成")

func get_spawned_enemies() -> Array[BaseEnemy]:
	"""获取当前生成的敌人列表"""
	# 清理无效的敌人引用
	var valid_enemies: Array[BaseEnemy] = []
	for enemy in spawned_enemies:
		if enemy and is_instance_valid(enemy):
			valid_enemies.append(enemy)
	
	spawned_enemies = valid_enemies
	return spawned_enemies

func _on_enemy_died(enemy: BaseEnemy):
	"""处理敌人死亡"""
	print("💀 敌人管理器：敌人死亡 ", enemy.name if enemy else "未知敌人")
	
	if enemy in spawned_enemies:
		spawned_enemies.erase(enemy)
		print("✅ 已从敌人列表中移除，剩余敌人: ", spawned_enemies.size())
	
	enemy_died.emit(enemy)
	
	# 检查是否所有敌人都已死亡（通关条件）
	if is_all_enemies_dead():
		print("🎉 所有敌人已被击败！游戏通关！")
		victory_achieved.emit()

func get_enemy_count() -> int:
	"""获取当前敌人数量"""
	return get_spawned_enemies().size()

func is_all_enemies_dead() -> bool:
	"""检查是否所有敌人都已死亡"""
	return get_enemy_count() == 0 
